<?xml version="1.0"?>

<xsl:stylesheet version="1.0"
	xmlns:xsl="http://www.w3.org/1999/XSL/Transform"
	xmlns:doc="http://xsltsl.org/xsl/documentation/1.0"
	xmlns:node="http://xsltsl.org/node"
	extension-element-prefixes="doc node">

  <doc:reference xmlns="">
    <referenceinfo>
      <releaseinfo role="meta">
	$Id: node.xsl,v 1.2 2001/05/11 05:44:26 balls Exp $
      </releaseinfo>
      <author>
	<surname>Ball</surname>
	<firstname>Steve</firstname>
      </author>
      <copyright>
	<year>2001</year>
	<holder>Steve Ball</holder>
      </copyright>
    </referenceinfo>

    <title>Node Templates</title>

    <partintro>
      <section>
	<title>Introduction</title>

	<para>This stylesheet module provides functions for reporting on or manipulating nodes and nodesets.</para>

      </section>
    </partintro>

  </doc:reference>

  <doc:template name="node:xpath" xmlns="">
    <refpurpose>Returns an XPath location path</refpurpose>

    <refdescription>
      <para>This template returns an XPath location path that uniquely identifies the given node within the document.</para>
    </refdescription>

    <refparameter>
      <variablelist>
	<varlistentry>
	  <term>node</term>
	  <listitem>
	    <para>The node to create an XPath for</para>
	  </listitem>
	</varlistentry>
      </variablelist>
    </refparameter>

    <refreturn>
      <para>Returns an XPath location path as a string.</para>
    </refreturn>
  </doc:template>

  <xsl:template name="node:xpath">
    <xsl:param name="node" select="."/>

    <xsl:choose>

      <xsl:when test="count($node/ancestor::*) &gt;= 1">
	<xsl:call-template name="node:xpath">
	  <xsl:with-param name="node" select="$node/.."/>
	</xsl:call-template>

	<xsl:text>/</xsl:text>

	<xsl:choose>

	  <xsl:when test="$node/self::*">
	    <xsl:value-of select="name($node)"/>
	    <xsl:variable name="number">
	      <xsl:value-of select="count($node/preceding-sibling::*[name() = name($node)]) + 1"/>
	    </xsl:variable>
	    <xsl:if test="$number &gt; 1">
	      <xsl:text>[</xsl:text>
	      <xsl:value-of select="$number"/>
	      <xsl:text>]</xsl:text>
	    </xsl:if>
	  </xsl:when>

	  <xsl:when test="$node/self::text()">
	    <xsl:text>text()</xsl:text>
	    <xsl:variable name="number">
	      <xsl:value-of select="count($node/preceding-sibling::text())"/>
	    </xsl:variable>
	    <xsl:if test="$number &gt; 1">
	      <xsl:text>[</xsl:text>
	      <xsl:value-of select="$number"/>
	      <xsl:text>]</xsl:text>
	    </xsl:if>
	  </xsl:when>

	  <xsl:otherwise>
	    <xsl:message>ERROR: unsupported node type, name <xsl:value-of select="name($node)"/></xsl:message>
	  </xsl:otherwise>

	</xsl:choose>
      </xsl:when>

      <xsl:otherwise>
	<!-- Document element -->
	<xsl:text>/</xsl:text>
	<xsl:value-of select="name($node)"/>
      </xsl:otherwise>

    </xsl:choose>

  </xsl:template>

  <doc:template name="node:type" xmlns="">
    <refpurpose>Return node type</refpurpose>

    <refdescription>
      <para>Returns the type of a node as a string.</para>
    </refdescription>

    <refparameter>
      <variablelist>
	<varlistentry>
	  <term>node</term>
	  <listitem>
	    <para>The node to get the type for</para>
	  </listitem>
	</varlistentry>
      </variablelist>
    </refparameter>

    <refreturn>
      <para>Returns node type as a string.  Values returned are:</para>
      <variablelist>
	<varlistentry>
	  <term>Element</term>
	  <listitem>
	    <para><literal>element</literal></para>
	  </listitem>
	</varlistentry>
	<varlistentry>
	  <term>Text Node</term>
	  <listitem>
	    <para><literal>text</literal></para>
	  </listitem>
	</varlistentry>
	<varlistentry>
	  <term>Comment</term>
	  <listitem>
	    <para><literal>comment</literal></para>
	  </listitem>
	</varlistentry>
	<varlistentry>
	  <term>Processing Instruction</term>
	  <listitem>
	    <para><literal>processing instruction</literal></para>
	  </listitem>
	</varlistentry>
      </variablelist>
    </refreturn>
  </doc:template>

  <xsl:template name="node:type">
    <xsl:param name="node" select="."/>

    <xsl:choose>
      <xsl:when test="$node/self::*">
	<xsl:text>element</xsl:text>
      </xsl:when>
      <xsl:when test="$node/self::text()">
	<xsl:text>text</xsl:text>
      </xsl:when>
      <xsl:when test="$node/self::comment()">
	<xsl:text>comment</xsl:text>
      </xsl:when>
      <xsl:otherwise>
	<xsl:text>processing instruction</xsl:text>
      </xsl:otherwise>
    </xsl:choose>
  </xsl:template>

</xsl:stylesheet>

